home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’95
/
Reminder Manager
/
Play.c
< prev
next >
Wrap
Text File
|
1995-06-24
|
5KB
|
219 lines
#define ON 1
#define OFF 0
#define NIL 0L
#include "Play.h"
#include "DebugDisplay.h"
#include "Lose.h"
#include "Chimer.h"
#include "limits.h"
// These are all kept in main.c
extern char PlayingFlag; // Noise in progress flag
extern short BallFrequency; // How often new balls are dropped
extern long ResolutionCounter; // Keep track of the times
extern long Resolution; // How many times to skip before going on
extern short wherewasI; // Loop Counter for Play1
extern unsigned long fudgefactor;
extern unsigned long fudgefactor2;
extern long starvation; // how often we get execution cycles
extern unsigned long starvTickCount; // the last time we got an execution chance
extern long starvIncrement; // the bonus multiplier fudge factor
extern long starvDecrement; // how many ticks to take off the stack when noise
extern long deltastarv;
extern long nextShower; // the minutes of the next time
extern long showerInterval; // minutes between showers
extern long showerDuration; // seconds (roughly)
extern long dissatisfaction; // how often we get to play notes
extern long dissDecrement; // how many ticks to take off the stack when noise
unsigned long curTickCount; // what time is it now?
#define BALLS 6
char Ball_List[BALLS];
#define STATES 7
#define EMPTY 0
#define DROP 1
#define CHIME1 2
#define CHIME2 3
#define CHIME3 4
#define CHIME4 5
#define CLINK 6
// StateList[1][3] means that the starting state is 1,
// the ending state is 3, and the probability of going from
// state 1 to state 3 is 0.20 (out of 1.00)
const float StateList[STATES][STATES] = {
1.00,0.00,0.00,0.00,0.00,0.00,0.00, // Start = EMPTY = 0
0.00,0.00,0.20,0.20,0.20,0.20,0.10, // Start = DROP = 1
0.40,0.00,0.05,0.25,0.05,0.15,0.10, // Start = Chime1 = 2
0.70,0.00,0.14,0.05,0.01,0.05,0.05, // Start = Chime2 = 3
0.40,0.00,0.05,0.15,0.05,0.25,0.10, // Start = Chime3 = 4
0.70,0.00,0.01,0.05,0.14,0.05,0.05, // Start = Chime4 = 5
1.00,0.00,0.00,0.00,0.00,0.00,0.00}; // Start = CLINK = 6
// MT DR 1 2 3 4 CLINK
void Init_Play(void)
{
int i;
unsigned long foo;
PlayingFlag = TRUE;
// init the ball list
for (i=0;i<BALLS;i++)
Ball_List[i]=EMPTY;
// Gimme random numbers
GetDateTime(&foo);
qd.randSeed = foo;
// Initialize the Counters
curTickCount = TickCount();
deltastarv = 0;
starvation = 0;
starvTickCount = curTickCount;
dissatisfaction = 0;
// Open the display window
OpenDisplay();
}
void Cease_Play(void)
{
PlayingFlag = FALSE;
DisposeDisplay();
}
// If a serious error happens (file system, etc)
void Explode(void)
{
Cease_Play();
A_Lose();
}
void Shower(void)
{
DateTimeRec d;
GetTime(&d);
// when the time comes, nail the storm value
if (d.minute==nextShower)
dissatisfaction = 255;
// after the duration of the storm, update the
// time of the next shower (which coincidentally
// causes the above clause to stop executing...)
if (d.second>showerDuration)
nextShower = (((1+(d.minute/showerInterval))*showerInterval) % 60);
}
void Play1(void)
{
short oldstate,newstate;
long tempstarv,tempsatis,i;
// Set up all the current counting stuff
curTickCount = TickCount();
tempstarv = (curTickCount-starvTickCount)/starvIncrement;
deltastarv = tempstarv-starvation;
starvation = (7*starvation+tempstarv)/8;
if (starvation>255) starvation = 255;
starvation -= starvDecrement;
if (starvation<0) starvation = 0;
if (starvation>fudgefactor2) dissatisfaction += (deltastarv/starvIncrement);
if (dissatisfaction>255) dissatisfaction = 255;
dissatisfaction -= dissDecrement;
if (dissatisfaction<0) dissatisfaction = 0;
Shower();
UpdateDisplay();
// use the storm variable to increase the likelihood
// that a noise will be made -- this makes the noise
// "trickle off."
for (i=0;i<(dissatisfaction*dissatisfaction);i+=50)
if ((deltastarv<20) && timetodrop())
{
DropBall();
break;
};
for (i=0;i<BALLS;i++)
{
oldstate = Ball_List[wherewasI];
newstate = ChangeStates(oldstate);
Ball_List[wherewasI] = newstate;
if ((newstate!=oldstate) && (newstate>1))
{
PlayAChime(newstate);
}
}
// Put the current tickcount into the old tickcount
starvTickCount = curTickCount;
}
Boolean timetodrop(void)
{
unsigned long ronda;
// if you're totally starved for time, don't go making noise.
if (starvation<fudgefactor)
{
ronda = (Random() & 0x7FFF);
return (ronda > (128*(BallFrequency)));
}
else
return FALSE;
}
void DropBall(void)
{
int i;
for (i=0;i<BALLS;i++)
if (Ball_List[i]==EMPTY)
{
Ball_List[i] = DROP;
break;
}
}
short ChangeStates(short startstate)
{
float foo;
float bar;
short i;
// hot-wire the obvious cases
if (startstate == EMPTY)
return EMPTY;
if (startstate == CLINK)
return EMPTY;
// Make foo be a random number from 0 to 1
foo = (float)(Random() & 0x7FFF) / (float)SHRT_MAX;
bar = 0.00;
for (i=0;i<STATES;i++)
{
bar += StateList[startstate][i];
if (bar > foo)
return i;
};
return EMPTY;
}